Typical HAL OSPI use cases for migration

This section provides information about the applicable HAL OSPI architecture use cases.

Use case: Octal PSRAM in memory-mapped mode (read and write operations)

Configuring an Octal PSRAM memory in memory-mapped mode and performing read/write operations.

Sequence diagram

Octal PSRAM in memory-mapped mode (read and write operations)

  @startuml
  == Initialization ==
  "Application" -> "OSPI" : HAL_OSPI_Init()
  "OSPI" --> "Application" : HAL_OK or HAL_INVALID_PARAM
  "Application" -> "System" : OSPI HW Initialization
  note right: Initialize GPIO
  "System" --> "Application" :

  == Configuration ==
  "Application" -> "OSPI" : HAL_OSPI_Command()
  note right: Program the OCTAL PSRAM to read/write
  "OSPI" --> "Application" : HAL_OK or HAL_ERROR

  "Application" -> "OSPI" : HAL_OSPI_MemoryMapped()
  "OSPI" --> "Application" :

  == Process ==
  "Application" -> "System" : Read/Write
  note right: Read/Write from internal memory
  "System" --> "Application" :
  @enduml

Code snippet

HAL1

HAL2

OSPI_HandleTypeDef OSPI;

 ospi.Instance = OSPI;
 ospi.Init.FifoThresholdByte = 4;
 ospi.Init.MemoryMode = HAL_OSPI_SINGLE_MEM;
 ospi.Init.MemoryType = HAL_OSPI_MEMTYPE_APMEM_16BITS;
 ospi.Init.MemorySize = HAL_OSPI_SIZE_256MB;
 ospi.Init.ChipSelectHighTimeCycle = 0x1U;
 ospi.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
 ospi.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
 ospi.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
 ospi.Init.ClockPrescaler = 0;
 ospi.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFT_NONE;
 ospi.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
 ospi.Init.ChipSelectBoundary = HAL_OSPI_BONDARYOF_8KB;
 ospi.Init.MaxTran = 0;
 ospi.Init.Refresh = 0;
 ospi.Init.MemorySelect = HAL_OSPI_CSSEL_NCS1;
 HAL_OSPI_Init(&ospi);

 OSPI_RegularCmdTypeDef scommand = {0};
 scommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
 scommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;
 scommand.InstructionWidth   = HAL_OSPI_INSTRUCTION_8_BITS;
 scommand.InstructionDTRMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
 scommand.Instruction        = 0xFFFFFFFF;
 scommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;
 scommand.AddressWidth       = HAL_OSPI_ADDRESS_16_BITS;
 scommand.AddressDTRMode     = HAL_OSPI_ADDRESS_DTR_ENABLE;
 scommand.Address            = Address;
 scommand.AlternateBytesMode = HAL_OSPI_ALT_BYTES_NONE;
 scommand.DataMode           = HAL_OSPI_DATA_8_LINES;
 scommand.DataDTRMode        = HAL_OSPI_DATA_DTR_ENABLE;
 scommand.DataLength         = 2;
 scommand.DummyCycles        = 0;
 scommand.DQSMode            = HAL_OSPI_DQS_DISABLE;





 HAL_OSPI_Command(&ospi, &scommand, OSPI_TIMEOUT);

 OSPI_MemoryMappedTypeDef sMemMappedCfg;
 sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE;
 sMemMappedCfg.TimeoutPeriodClock = 0x34;
 HAL_OSPI_MemoryMapped(&ospi, &sMemMappedCfg);
HAL_XSPI_Init(&xspi, HAL_OCTOSPI1);


/* Main peripheral configuration */
memory_config.mode = HAL_XSPI_MEMORY_SINGLE;
memory_config.type = HAL_XSPI_MEMORY_TYPE_APMEM_16BIT;
memory_config.size_bit = HAL_XSPI_MEMORY_SIZE_256MBIT;
memory_config.wrap_size_byte = HAL_XSPI_WRAP_NOT_SUPPORTED;
memory_config.clock_polarity = HAL_XSPI_CLOCK_LOW;
memory_config.cs_boundary = HAL_XSPI_CS_BOUNDARY_NONE;

timing_config.clk_prescaler = 0x1U;
timing_config.shift = HAL_XSPI_SAMPLE_SHIFT_NONE;
timing_config.hold = HAL_XSPI_DELAY_HOLD_NONE;
timing_config.cs_high_time_cycle = 0x1U;
timing_config.cs_release_time_cycle = 0x0U;
timing_config.cs_refresh_time_cycle = 0x0U;
timing_config.dlyb_state = HAL_XSPI_DLYB_ON;

xspi_config.memory = memory_config;
xspi_config.timing = timing_config;
if (HAL_XSPI_SetConfig(&hOCTOSPI1, &xspi_config) != HAL_OK)
{
  return NULL;
}

command.operation_type = HAL_XSPI_OPERATION_COMMON_CFG;
command.io_select = HAL_XSPI_IO_7_0;
command.instruction = WRITE_REG_CMD;
command.instruction_mode = HAL_XSPI_INSTRUCTION_8LINES;
command.instruction_width = HAL_XSPI_INSTRUCTION_8BIT;
command.instruction_dtr_mode_status = HAL_XSPI_INSTRUCTION_DTR_DISABLED;
command.addr = 0xFFFFFFFF;
command.addr_mode = HAL_XSPI_ADDR_8LINES;
command.addr_width = HAL_XSPI_ADDR_8BIT;
command.addr_dtr_mode_status = HAL_XSPI_ADDR_DTR_ENABLED;
command.alternate_bytes_mode = HAL_XSPI_ALTERNATE_BYTES_NONE;
command.data_mode = HAL_XSPI_REGULAR_DATA_8LINES;
command.data_dtr_mode_status = HAL_XSPI_DATA_DTR_ENABLED;
command.size_byte = 2;
command.dummy_cycle = 0;
command.dqs_mode_status = HAL_XSPI_DQS_DISABLED;
HAL_XSPI_SendRegularCmd(&xspi, &command, XSPI_TIMEOUT);

hal_xspi_memory_mapped_config_t mem_mapped_cfg;
mem_mapped_cfg.timeout_activation = HAL_XSPI_TIMEOUT_ENABLE;
mem_mapped_cfg.timeout_period_cycle = 0x34;
HAL_XSPI_StartMemoryMappedMode(&xspi, &mem_mapped_cfg);
HAL_XSPI_StopMemoryMappedMode(&xspi);

Key changes

  1. In HAL2, OSPI APIs are replaced by XSPI APIs (for example, HAL_OSPI_Init() becomes HAL_XSPI_Init()).

  2. In HAL2, configuration is applied using HAL_XSPI_SetConfig() after initialization.

  3. In HAL2, memory-mapped mode is started and stopped using HAL_XSPI_StartMemoryMappedMode() and HAL_XSPI_StopMemoryMappedMode().


Use case: Initialization and configuration of a HyperBus memory

Initialization and configuration of a HyperBus memory.

Sequence diagram

Initialization and configuration of a HyperBus memory

  @startuml

  == Initialization ==
  group opt
  "Application" -> "OSPI" : HAL_OSPIM_Config()
  "OSPI" --> "Application" :
  end group
  "Application" -> "OSPI" : HAL_OSPI_Init()
  "OSPI" --> "Application" :
  "Application" -> "System" : OSPI HW Initialization
  "System" --> "Application"

  == Configuration ==
  "Application" -> "OSPI" : HAL_OSPI_HyperbusCfg()
  "OSPI" --> "Application"

  @enduml

Code snippet

HAL1

HAL2

/* OSPIM configuration as mention in the use case :
   Memory initialization using OSPIM configuration */

OSPI_HandleTypeDef ospi;

ospi.Instance = OSPI;
ospi.Init.FifoThresholdByte = 1;
ospi.Init.MemoryMode = HAL_OSPI_SINGLE_MEM;
ospi.Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
ospi.Init.MemorySize = HAL_OSPI_SIZE_16B;
ospi.Init.ChipSelectHighTimeCycle = 1;
ospi.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
ospi.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
ospi.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
ospi.Init.ClockPrescaler = 0;
ospi.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFT_NONE;
ospi.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
ospi.Init.ChipSelectBoundary = 0x00U;
ospi.Init.MaxTran = 0;
ospi.Init.Refresh = 0;
ospi.Init.MemorySelect = HAL_OSPI_CSSEL_NCS1;

HAL_OSPI_Init(&ospi);



sHyperBusCfg.RWRecoveryTimeCycle = 0;
sHyperBusCfg.AccessTimeCycle = 0;
sHyperBusCfg.WriteZeroLatency = HAL_OSPI_NO_LATENCY_ON_WRITE;
sHyperBusCfg.LatencyMode = HAL_OSPI_VARIABLE_LATENCY;




HAL_OSPI_HyperbusCfg(&ospi, &sHyperBusCfg, OSPI_TIMEOUT);
/* XSPIM configuration as mentioned in the use case :
 Memory initialization using XSPIM configuration */

hal_xspi_handle_t hOCTOSPI1;
HAL_XSPI_Init(&hOCTOSPI1, HAL_OCTOSPI1);

hal_xspi_config_t xspi_config;
hal_xspi_memory_config_t memory_config;
hal_xspi_timing_config_t timing_config;
hal_xspi_hyperbus_config_t hyperbus_config;

memory_config.mode = HAL_XSPI_MEMORY_SINGLE;
memory_config.clock_polarity = HAL_XSPI_CLOCK_LOW;
memory_config.type = HAL_XSPI_MEMORY_TYPE_HYPERBUS;
memory_config.size_bit = HAL_XSPI_MEMORY_SIZE_16BIT;
memory_config.wrap_size_byte = HAL_XSPI_WRAP_NOT_SUPPORTED;
memory_config.cs_boundary = HAL_XSPI_CS_BOUNDARY_NONE;

timing_config.clk_prescaler = 0x1U;
timing_config.shift = HAL_XSPI_SAMPLE_SHIFT_NONE;
timing_config.hold = HAL_XSPI_DELAY_HOLD_NONE;
timing_config.cs_high_time_cycle = 0x1U;
timing_config.cs_release_time_cycle = 0x0U;
timing_config.cs_refresh_time_cycle = 0x0U;
timing_config.dlyb_state = HAL_XSPI_DLYB_ON;

hyperbus_config.rw_recovery_time_cycle = 0x0U;
hyperbus_config.access_time_cycle = 0x0U;
hyperbus_config.write_zero_latency = HAL_XSPI_WRITE_ZERO_LATENCY_DISABLED;
hyperbus_config.latency_mode = HAL_XSPI_LATENCY_VARIABLE;

xspi_config.memory = memory_config;
xspi_config.timing = timing_config;
xspi_config.hyperbus = hyperbus_config;
HAL_XSPI_SetConfig(&hOCTOSPI1, &xspi_config);

Key changes

  1. In HAL2, OSPI APIs are replaced by XSPI APIs (for example, HAL_OSPI_Init() becomes HAL_XSPI_Init()).

  2. In HAL2, HyperBus configuration is provided as part of HAL_XSPI_SetConfig() instead of calling HAL_OSPI_HyperbusCfg().


Use case: Starting a write/read in polling indirect mode

Starting a write/read operation in polling indirect mode.

Sequence diagram

Starting a write/read operation in polling indirect mode

  @startuml

    == Initialization and configuration ==

    == Process polling mode ==
    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    note right: Enable write operation
    "OSPI" --> "Application" : HAL_OK or HAL_ERROR

    "Application" -> "OSPI" : HAL_OSPI_AutoPolling()
    note right: Reconfigure OSPI to automatic polling mode to wait for write enabling
    "OSPI" --> "Application" : match completed

    group opt
    "Application" -> "OSPI" : HAL_OSPI_SetFifoThreshold()
    note right: Configure the fifo threshold
    end group

    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    "OSPI" --> "Application" : HAL_OK or HAL_ERROR

    "Application" -> "OSPI" : HAL_OSPI_Transmit()
    "OSPI" --> "Application" :

    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    "OSPI" --> "Application" : HAL_OK or HAL_ERROR

    "Application" -> "OSPI" : HAL_OSPI_AutoPolling()
    note right: Reconfigure OSPI to automatic polling mode to wait end of operation
    "OSPI" --> "Application" : match completed

    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    "OSPI" --> "Application" : HAL_OK or HAL_ERROR

    "Application" -> "OSPI" : HAL_OSPI_Receive()
    "OSPI" --> "Application" :

    @enduml

Code snippet

HAL1

HAL2

/* Perform the init and configuration as per the first use case*/

OSPI_HandleTypeDef ospi;

OSPI_RegularCmdTypeDef sCommand={0};
scommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
scommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;
scommand.InstructionWidth   = HAL_OSPI_INSTRUCTION_8_BITS;
scommand.InstructionDTRMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
scommand.Instruction        = WRITE_REG_CMD;
scommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;
scommand.AddressWidth       = HAL_OSPI_ADDRESS_32_BITS;
scommand.AddressDTRMode     = HAL_OSPI_ADDRESS_DTR_ENABLE;
scommand.Address            = Address;
scommand.AlternateBytesMode = HAL_OSPI_ALT_BYTES_NONE;
scommand.DataMode           = HAL_OSPI_DATA_8_LINES;
scommand.DataDTRMode        = HAL_OSPI_DATA_DTR_ENABLE;
scommand.DataLength         = 2;
scommand.DummyCycles        = 0;
scommand.DQSMode            = HAL_OSPI_DQS_DISABLE;



HAL_OSPI_Command(&ospi, &scommand, OSPI_TIMEOUT);

HAL_OSPI_AutoPolling(&ospi, &sConfig, OSPI_TIMEOUT);

HAL_OSPI_SetFifoThreshold(&ospi, 4);

HAL_OSPI_Command(&ospi, &scommand, OSPI_TIMEOUT);

HAL_OSPI_Transmit(&ospi, &reg, OSPI_TIMEOUT);

HAL_OSPI_Command(&ospi, &sCommand, OSPI_TIMEOUT);

HAL_OSPI_AutoPolling(&ospi, &sConfig, OSPI_TIMEOUT);

HAL_OSPI_Command(&ospi, &sCommand, OSPI_TIMEOUT);

HAL_OSPI_Receive(&ospi, (uint8_t *)aRxBuffer, OSPI_TIMEOUT);
/* Perform the init and configuration as per the first use case*/

hal_xspi_handle_t xspi;

command.operation_type = HAL_XSPI_OPERATION_COMMON_CFG;
command.io_select = HAL_XSPI_IO_7_0;
command.alternate_bytes = 0U;
command.alternate_bytes_width = HAL_XSPI_ALTERNATE_BYTES_8BIT;
command.alternate_bytes_mode = HAL_XSPI_ALTERNATE_BYTES_NONE;
command.alternate_bytes_dtr_mode_status = HAL_XSPI_ALTERNATE_BYTES_DTR_DISABLED;
/* Specific parameters for the Sector Erase command */
command.instruction = WRITE_REG_CMD;
command.instruction_mode = HAL_XSPI_INSTRUCTION_8LINES;
command.instruction_width = HAL_XSPI_INSTRUCTION_32BIT;
command.instruction_dtr_mode_status = HAL_XSPI_INSTRUCTION_DTR_DISABLED;
command.addr = MX25_FIRST_BLOCK_ADDR;
command.addr_mode = HAL_XSPI_ADDR_8LINES;
command.addr_width = HAL_XSPI_ADDR_32BIT;
command.addr_dtr_mode_status = HAL_XSPI_ADDR_DTR_ENABLED;
command.data_mode = HAL_XSPI_REGULAR_DATA_NONE;
command.data_dtr_mode_status = HAL_XSPI_DATA_DTR_ENABLED;
command.dummy_cycle = 0;
command.dqs_mode_status = HAL_XSPI_DQS_DISABLED;
command.size_byte = 2U;
HAL_XSPI_SendRegularCmd(&xspi, &command, XSPI_TIMEOUT);

HAL_XSPI_ExecRegularAutoPoll(&xspi, &pPollingModeCfg, XSPI_TIMEOUT);

HAL_XSPI_SetFifoThreshold(&xspi, 4);

HAL_XSPI_SendRegularCmd(&xspi, &command, XSPI_TIMEOUT);

HAL_XSPI_Transmit(&xspi, p_data, XSPI_TIMEOUT);

HAL_XSPI_SendRegularCmd(&xspi, &command, XSPI_TIMEOUT);

HAL_XSPI_ExecRegularAutoPoll(&xspi, &pPollingModeCfg, XSPI_TIMEOUT);

HAL_XSPI_SendRegularCmd(&xspi, &command, XSPI_TIMEOUT);

HAL_XSPI_Receive(&xspi, (uint8_t *)aRxBuffer, XSPI_TIMEOUT);

Key changes

  1. In HAL2, OSPI APIs are replaced by XSPI APIs (for example, HAL_OSPI_Command() becomes HAL_XSPI_SendRegularCmd()).

  2. In HAL2, the polling sequence uses HAL_XSPI_ExecRegularAutoPoll() for automatic polling.


Use case: Starting a write/read in interrupt mode

Starting a write/read operation in interrupt mode.

Sequence diagram

Starting a write/read operation in interrupt mode

  @startuml

    == Initialization and configuration ==

    == Process interrupt mode ==
    "Application" -> "OSPI" : HAL_OSPI_Command_IT()
    "IRQHandler" <-  : Interrupt
    "IRQHandler" -> "OSPI" : HAL_OSPI_IRQHandler()
    "Application" -> "OSPI" : HAL_OSPI_CmdCpltCallback()

    "Application" -> "OSPI" : HAL_OSPI_SetFifoThreshold()

    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    "OSPI" --> "Application" :

    "Application" -> "OSPI" : HAL_OSPI_Transmit_IT()

    "IRQHandler" <-  : Interrupt
    "IRQHandler" -> "OSPI" : HAL_OSPI_IRQHandler()
    "Application" -> "OSPI" : HAL_OSPI_TxCpltCallback()

    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    "OSPI" --> "Application" :

    "Application" -> "OSPI" : HAL_OSPI_Receive_IT()
    "IRQHandler" <-  : Interrupt
    "IRQHandler" -> "OSPI" : HAL_OSPI_IRQHandler()
    "OSPI" --> "Application" : HAL_OSPI_RxCpltCallback()

  @enduml

Code snippet

HAL1

HAL2

/* Perform the init and configuration as per the first use case */

OSPI_HandleTypeDef ospi;
OSPI_RegularCmdTypeDef sCommand = {0};

/* Prepare command parameters in sCommand (instruction/address/data modes, etc.) */

/* Start command sequence in interrupt mode */
if (HAL_OSPI_Command_IT(&ospi, &sCommand) != HAL_OK)
{
  Error_Handler();
}

/* Called from HAL_OSPI_IRQHandler() context */
void HAL_OSPI_CmdCpltCallback(OSPI_HandleTypeDef *hospi)
{
  HAL_OSPI_SetFifoThreshold(hospi, 4);

  /* Transmit in interrupt mode */
  HAL_OSPI_Transmit_IT(hospi, pTxData);
}

/* Called from HAL_OSPI_IRQHandler() context */
void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Optionally send next command before receiving */
  HAL_OSPI_Command(hospi, &sCommand, OSPI_TIMEOUT);
  HAL_OSPI_Receive_IT(hospi, pRxData);
}

/* Called from HAL_OSPI_IRQHandler() context */
void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *hospi)
{
  /* Transfer complete */
  (void)hospi;
}
/* Perform the init and configuration as per the first use case */

hal_xspi_handle_t xspi;
hal_xspi_regular_cmd_t command = {0};

/* Prepare command parameters in command (instruction/address/data modes, etc.) */

/* Start command sequence in interrupt mode */
if (HAL_XSPI_SendRegularCmd_IT(&xspi, &command, XSPI_TIMEOUT) != HAL_OK)
{
  Error_Handler();
}

/* Called from HAL_XSPI_IRQHandler() context */
void HAL_XSPI_CmdCpltCallback(hal_xspi_handle_t *hxspi)
{
  /* Transmit in interrupt mode */
  HAL_XSPI_Transmit_IT(hxspi, pTxData);
}

/* Called from HAL_XSPI_IRQHandler() context */
void HAL_XSPI_TxCpltCallback(hal_xspi_handle_t *hxspi)
{
  /* Optionally send next command before receiving */
  HAL_XSPI_SendRegularCmd(hxspi, &command, XSPI_TIMEOUT);
  HAL_XSPI_Receive_IT(hxspi, pRxData);
}

/* Called from HAL_XSPI_IRQHandler() context */
void HAL_XSPI_RxCpltCallback(hal_xspi_handle_t *hxspi)
{
  /* Transfer complete */
  (void)hxspi;
}

Key changes

  1. In HAL2, OSPI interrupt APIs are replaced by XSPI interrupt APIs (for example, HAL_OSPI_Command_IT() becomes HAL_XSPI_SendRegularCmd_IT()).

  2. In HAL2, the IRQ handling and callbacks are updated to XSPI naming.

Related examples in HAL2

Example Name

Description

example_hal_xspi_psram_write_read_it

How to erase part of a PSRAM memory, write data in Interrupt mode, read data in Interrupt mode.


Use case: Starting a write/read in DMA mode for regular memory

Starting a write/read operation in DMA mode for regular memory.

Sequence diagram

Starting a write/read operation in DMA mode for regular memory

  @startuml

    == Initialization and configuration ==

    == Process DMA mode ==
    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    note right: Reconfigure write operation
    "OSPI" --> "Application" :

    "Application" -> "OSPI" : HAL_OSPI_Transmit_DMA()
    note right: Start DMA channel transfer with interrupt enabled
    "IRQHandler" <-  : Interrupt
    "IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
    "DMA" -> "OSPI" : DMA_Trasfer_Complete
    "OSPI" --> "Application" : HAL_OSPI_TxCpltCallback()

    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    "Application" -> "OSPI" : HAL_OSPI_AutoPolling_IT()
    note right : Reconfigure OSPI to AutoPolling mode to wait end of operation

    "IRQHandler" <-  : Interrupt
    "IRQHandler" --> "OSPI" : HAL_OSPI_IRQHandler()
    "OSPI" --> "Application" : HAL_OSPI_StatusMatchCallback()

    "Application" -> "OSPI" : HAL_OSPI_Command()/HAL_OSPI_HyperbusCmd()
    note right: Reconfigure read operation
    "OSPI" --> "Application" :

    "Application" -> "OSPI" : HAL_OSPI_Receive_DMA()
    note right: Start DMA channel transfer with interrupt enabled

    "IRQHandler" <-  : Interrupt
    "IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
    "DMA" -> "OSPI" : DMA_Transfer_Complete
    "OSPI" --> "Application" : HAL_OSPI_RxCpltCallback()


    @enduml

Code snippet

HAL1

HAL2

OSPI_HandleTypeDef ospi;
OSPI_RegularCmdTypeDef scommand = {0};

scommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
scommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;
scommand.InstructionWidth   = HAL_OSPI_INSTRUCTION_8_BITS;
scommand.InstructionDTRMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
scommand.Instruction        = WRITE_REG_CMD;
scommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;
scommand.AddressWidth       = HAL_OSPI_ADDRESS_32_BITS;
scommand.AddressDTRMode     = HAL_OSPI_ADDRESS_DTR_ENABLE;
scommand.AlternateBytesMode = HAL_OSPI_ALT_BYTES_NONE;
scommand.DataMode           = HAL_OSPI_DATA_8_LINES;
scommand.DataDTRMode        = HAL_OSPI_DATA_DTR_ENABLE;
scommand.DataLength         = 2;
scommand.DummyCycles        = 0;
scommand.DQSMode            = HAL_OSPI_DQS_DISABLE;





HAL_OSPI_Command(&ospi, &scommand, OSPI_TIMEOUT);

HAL_OSPI_Transmit_DMA(&ospi, data);

HAL_DMA_IRQHandler(&ospi);

HAL_OSPI_TxCpltCallback(&ospi);

HAL_OSPI_Command(&ospi, &command, OSPI_TIMEOUT);






HAL_OSPI_AutoPolling_IT(&ospi, &sConfig);

ospi_IRQHandler(&ospi);

HAL_OSPI_StatusMatchCallback(&ospi);

HAL_OSPI_Command(&ospi, &command, OSPI_TIMEOUT);

HAL_OSPI_Receive_DMA(&ospi, (uint8_t *)aRxBuffer);

HAL_DMA_IRQHandler(&ospi);

HAL_OSPI_RxCpltCallback(&ospi);


void HAL_OSPI_TxCpltCallback(OSPI_HandleTypeDef *ospi)
{
  // USER CODE
}

void HAL_OSPI_RxCpltCallback(OSPI_HandleTypeDef *ospi)
{
  // USER CODE
}
hal_xspi_handle_t xspi;


command.operation_type = HAL_XSPI_OPERATION_COMMON_CFG;
command.io_select = HAL_XSPI_IO_7_0;
command.alternate_bytes = 0U;
command.alternate_bytes_width = HAL_XSPI_ALTERNATE_BYTES_8BIT;
command.alternate_bytes_mode = HAL_XSPI_ALTERNATE_BYTES_NONE;
command.alternate_bytes_dtr_mode_status = HAL_XSPI_ALTERNATE_BYTES_DTR_DISABLED;
/* Specific parameters for the Sector Erase command */
command.instruction = WRITE_REG_CMD;
command.instruction_mode = HAL_XSPI_INSTRUCTION_8LINES;
command.instruction_width = HAL_XSPI_INSTRUCTION_32BIT;
command.instruction_dtr_mode_status = HAL_XSPI_INSTRUCTION_DTR_DISABLED;
command.addr = MX25_FIRST_BLOCK_ADDR;
command.addr_mode = HAL_XSPI_ADDR_8LINES;
command.addr_width = HAL_XSPI_ADDR_8BIT;
command.addr_dtr_mode_status = HAL_XSPI_ADDR_DTR_ENABLED;
command.data_mode = HAL_XSPI_REGULAR_DATA_NONE;
command.data_dtr_mode_status = HAL_XSPI_DATA_DTR_ENABLED;
command.dummy_cycle = 0;
command.dqs_mode_status = HAL_XSPI_DQS_DISABLED;
command.size_byte = 2;
HAL_XSPI_SendRegularCmd(xspi, &command, XSPI_TIMEOUT);

HAL_XSPI_Transmit_DMA(xspi, data);

HAL_DMA_IRQHandler(xspi);

HAL_XSPI_TxCpltCallback(xspi);

HAL_XSPI_SendRegularCmd(xspi, &command, XSPI_TIMEOUT);

sConfig.MatchMode           = HAL_XSPI_MATCH_MODE_AND;
sConfig.AutomaticStop       = HAL_XSPI_AUTOMATIC_STOP_ENABLE;
sConfig.IntervalTime        = 0x10;
sConfig.MatchMask           = WRITE_ENABLE_MASK_VALUE;
sConfig.MatchValue          = WRITE_ENABLE_MATCH_VALUE;
HAL_XSPI_ExecRegularAutoPoll_IT(xspi, &sConfig);

xspi_IRQHandler(&xspi);

HAL_XSPI_StatusMatchCallback(&xspi);

HAL_XSPI_SendRegularCmd(xspi, &command, XSPI_TIMEOUT);

HAL_XSPI_Receive_DMA(&xspi, (uint8_t *)aRxBuffer);

HAL_DMA_IRQHandler(&xspi);

HAL_XSPI_RxCpltCallback(&xspi);


void HAL_XSPI_TxCpltCallback(XSPI_HandleTypeDef *hxspi)
{
  // USER CODE
}

void HAL_XSPI_RxCpltCallback(XSPI_HandleTypeDef *hxspi)
{
  // USER CODE
}

Key changes

  1. In HAL2, OSPI DMA APIs are replaced by XSPI DMA APIs (for example, HAL_OSPI_Transmit_DMA() becomes HAL_XSPI_Transmit_DMA()).

  2. In HAL2, automatic polling in interrupt mode uses HAL_XSPI_ExecRegularAutoPoll_IT().

Related examples in HAL2

Example Name

Description

example_hal_xspi_nor_write_read_dma

How to erase part of a NOR memory, write data in DMA mode, read data in DMA mode.


Use case: Memory initialization using XSPIM configuration

Memory initialization using XSPIM configuration.

Sequence diagram

Memory initialization using XSPIM configuration

  @startuml

  == Initialization ==
  "Application" -> "OSPI" : HAL_OSPIM_Config()
  "OSPI" --> "Application" :
  "Application" -> "OSPI" : HAL_OSPI_Init()
  "OSPI" --> "Application" :
  "Application" -> "System" : OSPI HW Initialization
  "System" --> "Application"

  == Process ==
  note over OSPI, Application: **Continue the process according to the targeted scenario**

  @enduml

Code snippet

HAL1

HAL2

OSPI_HandleTypeDef ospi;
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
sOspiManagerCfg.nCSOverride = HAL_OSPI_CSSEL_OVR_NCS1;
sOspiManagerCfg.IOPort = HAL_OSPIM_IOPORT_1;



HAL_OSPIM_Config(&ospi, &sOspiManagerCfg, OSPI_TIMEOUT);

ospi.Instance = OSPI;
ospi.Init.FifoThresholdByte = 4;
ospi.Init.MemoryMode = HAL_OSPI_SINGLE_MEM;
ospi.Init.MemoryType = HAL_OSPI_MEMTYPE_APMEM_16BITS;
ospi.Init.MemorySize = HAL_OSPI_SIZE_256MB;
ospi.Init.ChipSelectHighTimeCycle = 5;
ospi.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
ospi.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
ospi.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
ospi.Init.ClockPrescaler = 0;
ospi.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFT_NONE;
ospi.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
ospi.Init.ChipSelectBoundary = HAL_OSPI_BONDARYOF_8KB;
ospi.Init.MaxTran = 0;
ospi.Init.Refresh = 0;
ospi.Init.MemorySelect = HAL_OSPI_CSSEL_NCS1;
HAL_OSPI_Init(&ospi);
hal_xspi_handle_t xspi;
hal_xspi_xspim_config_t sOspiManagerCfg;
sOspiManagerCfg.port1.clk = HAL_XSPI_XSPIM_XSPI1;
sOspiManagerCfg.port1.dqs = HAL_XSPI_XSPIM_XSPI1;
sOspiManagerCfg.port1.ncs = HAL_XSPI_XSPIM_XSPI1;
sOspiManagerCfg.port1.io_low = HAL_XSPI_XSPIM_XSPI1_IO_LOW;
sOspiManagerCfg.port1.io_high = HAL_XSPI_XSPIM_XSPI1_IO_HIGH;
sOspiManagerCfg.req_ack_cycle = 1U;
HAL_XSPI_XSPIM_SetConfig(&sOspiManagerCfg);

















HAL_XSPI_Init(&xspi, HAL_OCTOSPI1);

hal_xspi_config_t HAL_XSPI_Global_Cfg_Struct;
HAL_XSPI_Global_Cfg_Struct.memory = HAL_XSPI_Mem_Cfg_Struct;
HAL_XSPI_Global_Cfg_Struct.timing = HAL_XSPI_Timing_Cfg_Struct;
HAL_XSPI_SetConfig(&xspi, &HAL_XSPI_Global_Cfg_Struct);

Key changes

  1. In HAL2, OSPIM configuration is performed through XSPI XSPIM configuration (for example, HAL_OSPIM_Config() becomes HAL_XSPI_XSPIM_SetConfig()).

  2. In HAL2, OSPI initialization and configuration are replaced by HAL_XSPI_Init() and HAL_XSPI_SetConfig().


Use case: Initializing memory with a delay block to adjust timing

Initializing memory with a delay block to adjust timing.

Sequence diagram

Initializing memory with a delay block to adjust timing

  @startuml

    == Initialization ==
    "Application" -> "OSPI" : HAL_OSPI_Init()
    "OSPI" --> "Application" : HAL_OK or HAL_INVALID_PARAM
    "Application" -> "System" : OSPI HW Initialization
    note right: Initialize GPIO
    "System" --> "Application" :

    == Configuration ==

    "Application" -> "OSPI" : HAL_OSPI_DLYB_SetConfig()
    note right: Set delay block configuration
    "OSPI" --> "Application" : HAL_OK or HAL_ERROR or HAL_INVALID_PARAM

    == Process polling mode ==

    note over OSPI, Application: **Continue the process operations according to the targeted scenario**

  @enduml

Code snippet

HAL1

HAL2

/* Init and config sequence */
HAL_OSPI_Init(&ospi);





HAL_OSPI_DLYB_SetConfig(&ospi, 2);
/* */
hal_xspi_config_t HAL_XSPI_Global_Cfg_Struct;

HAL_XSPI_Init(&xspi, HAL_OCTOSPI);

HAL_XSPI_SetConfig(&xspi, &HAL_XSPI_Global_Cfg_Struct);

HAL_XSPI_DLYB_SetConfigDelay(&xspi, 2);
HAL_XSPI_DLYB_Enable(&xspi);

Key changes

  1. In HAL2, OSPI APIs are replaced by XSPI APIs (for example, HAL_OSPI_Init() becomes HAL_XSPI_Init()).

  2. In HAL2, delay block configuration uses HAL_XSPI_DLYB_SetConfigDelay() and can be enabled using HAL_XSPI_DLYB_Enable().